home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Turnbull China Bikeride
/
Turnbull China Bikeride - Disc 2.iso
/
ACORNUSERS
/
EMULATOR
/
MAGICKIT
/
assembler
/
c
/
main
< prev
next >
Wrap
Text File
|
1998-04-27
|
7KB
|
354 lines
/* Assembler for the HuC6280 microprocessor found in the PC Engine console.
* ----
* This program was originaly a 6502 assembler written by
* J. H. Van Ornum, it has been modified by David Michel
* to support the HuC6280.
*
* This program is freeware. You are free to distribute, use and
* modifiy it as you wish.
*
* Enjoy!
*/
#include <stdio.h>
#include <string.h>
#include "defs.h"
#include "externs.h"
#include "vars.h"
/***** DEFINES *************/
/***** GLOBALS *************/
int infile_error;
int infile_num;
int switch_throwback;
char i_file[128];
char o_file[128];
char l_file[128];
FILE *iptr;
FILE *optr;
FILE *lptr;
struct t_input_info input_file[8];
/*----------------*/
int field[] = {
SFIELD,
SFIELD + 8,
SFIELD + 14,
SFIELD + 14,
SFIELD + 14,
SFIELD + 14,
/* SFIELD + 23, */
/* SFIELD + 43, */
/* SFIELD + 75 */
};
/***** EXTERNALS ***********/
/*
* main :
* -----
*
*/
main(int argc, char **argv)
{
char *p;
int i, usage = 1;
i_file[0] = o_file[0] = l_file[0] = 0;
switch_throwback = 0;
for (i = 1; i < argc && usage; i++) {
if (!strcmp(argv[i], "-o")) strcpy(o_file, argv[++i]);
else if (!strcmp(argv[i], "-throwback")) switch_throwback = 1;
else if (argv[i][0] != '-') {
if (i_file[0] == 0) strcpy(i_file, argv[i]);
else if (l_file[0] == 0) strcpy(l_file, argv[i]);
else usage = 0;
}
else usage = 0;
}
if (usage == 0 || o_file[0] == 0 || i_file[0] == 0) {
fprintf(stderr, "Syntax: magicasm <source file> -o <output file> [-throwback] [<list file>]\n");
return(1);
}
if (l_file[0] == 0) strcpy(l_file, "null:$.l_file");
/* -- auto-add the file extensions. */
/* strupr(i_file);*/
/* if (p = strrchr(i_file, '.')) {
if (!strchr(p, '\\'))
*p = '\0';
else
p = NULL;
}
strcpy(o_file, i_file);
strcpy(l_file, i_file);
strcat(o_file, ".PCE");
strcat(l_file, ".LST");
if (p)
*p = '.';
else
strcat(i_file, ".ASM");*/
/* -- open the input file. */
if (open_input(i_file)) {
fprintf(stdout, "Can not open input file '%s'!\n", i_file);
exit(1);
}
/* -- clear the code array. */
memset(rom, 8192 * 128, 0);
/* -- assemble. */
for (i = 0; i < 256; i++) {
hash_tbl[i] = NULL;
macro_tbl[i] = NULL;
}
for (pass = FIRST_PASS; pass <= LAST_PASS; pass++) {
infile_error = -1;
errcnt = 0;
page = 0;
bank = 0;
max_bank = 0;
loccnt = 0;
slnum = 0;
mcounter = 0;
mcntmax = 0;
clist = 0;
mlist = 0;
glablptr = NULL;
rsbase = 0;
for (i = 0; i < 128; i++) {
bank_offset[i] = 0;
bank_page[i] = 0;
}
while (readline() != -1) {
assemble();
if (loccnt > 0x2000) {
error("Out of range, bank offset > $1FFF!");
break;
}
}
if (errcnt) {
if (switch_throwback == 2) {
DDEUtils_ThrowbackEnd();
switch_throwback = 1;
}
fprintf(stdout, "# %d ERROR(s)\n", errcnt);
break;
}
rewind(iptr);
if (pass == FIRST_PASS) {
if (xlist) {
if ((lptr = fopen(l_file, "w")) == NULL) {
fprintf(stdout, "Can not open listing file '%s'!\n", l_file);
exit(1);
}
fprintf(lptr, "#[1] %s\n", input_file[1].name);
}
}
}
if (errcnt == 0) {
if ((optr = fopen(o_file, "wb")) == NULL) {
fprintf(stdout, "Can not open object file '%s'!\n", o_file);
exit(1);
}
fwrite(rom, 8192, max_bank + 1, optr);
fclose(optr);
}
if (xlist)
fclose(lptr);
fclose(iptr);
return(0);
}
/*
* readline :
* ---------
* reads and formats an input line.
*
*/
readline()
{
char *ptr, *arg, num[8];
int j, n;
int i; /* pointer into prlnbuf */
int c; /* current character */
int temp; /* temp used for line number conversion */
start:
for (i = 0; i < LAST_CH_POS; i++)
prlnbuf[i] = ' ';
/* if expand_macro get line from macro buffer */
if (expand_macro) {
if (mlptr == NULL) {
while (mlptr == NULL) {
midx--;
mlptr = mstack[midx];
mcounter = mcntstack[midx];
if (midx == 0) {
mlptr = NULL;
expand_macro = 0;
break;
}
}
}
if (mlptr) {
i = SFIELD;
ptr = mlptr->data;
while (c = *ptr++) {
if (c != '\\')
prlnbuf[i++] = c;
else {
c = *ptr++;
prlnbuf[i] = '\0';
if (c == '@') {
n = 4;
sprintf(num, "%04i", mcounter);
arg = num;
}
else if (c >= '1' && c <= '9') {
j = c - '1';
n = strlen(marg[midx][j]);
arg = marg[midx][j];
}
else {
error("Invalid macro argument index!");
return (-1);
}
if ((i + n) >= LAST_CH_POS - 1) {
error("Invalid line length!");
return (-1);
}
strncpy(&prlnbuf[i], arg, n);
i += n;
}
if (i >= LAST_CH_POS - 1)
i = LAST_CH_POS - 1;
}
prlnbuf[i] = '\0';
mlptr = mlptr->next;
return (0);
}
}
/* put source line number into prlnbuf. */
i = 4;
temp = ++slnum;
while (temp != 0) {
prlnbuf[i--] = temp % 10 + '0';
temp /= 10;
}
i = SFIELD;
while ((c = getc(iptr)) != '\n') {
if(c == '\r')
continue;
prlnbuf[i++] = c;
if (c == '\t') {
prlnbuf[--i] = ' ';
i += (8 - ((i - SFIELD) % 8));
}
else if (c == EOF) {
if (close_input())
return(-1);
goto start;
}
if (i >= LAST_CH_POS - 1)
i = LAST_CH_POS - 1;
}
prlnbuf[i] = '\0';
return(0);
}
/*
* open_input :
* -----------
* open an input file, up to 7 levels.
*
*/
open_input(char *name)
{
FILE *fptr;
char *p;
int i;
if (infile_num == 7) {
error("Too many include levels!");
return (1);
}
if (infile_num) {
input_file[infile_num].lnum = slnum;
input_file[infile_num].fptr = iptr;
}
strcpy(i_file, name);
/* strupr(i_file);
if (p = strrchr(i_file, '.')) {
if (strchr(p, '\\'))
strcat(i_file, ".ASM");
} else
strcat(i_file, ".ASM");*/
if (infile_num) {
for (i = 1; i < infile_num; i++) {
if (!strcmp(input_file[i].name, i_file)) {
error("Repeated include file!");
return (1);
}
}
}
if ((fptr = fopen(i_file, "r")) == NULL)
return (-1);
iptr = fptr;
slnum = 0;
infile_num++;
input_file[infile_num].fptr = fptr;
strcpy(input_file[infile_num].name, i_file);
if ((pass == LAST_PASS) && (xlist))
fprintf(lptr, "#[%i] %s\n", infile_num, input_file[infile_num].name);
return (0);
}
/*
* close_input :
* ------------
* close an input file, return -1 if no more files in the stack.
*
*/
close_input()
{
if (infile_num <= 1)
return (-1);
fclose(iptr);
infile_num--;
infile_error = -1;
slnum = input_file[infile_num].lnum;
iptr = input_file[infile_num].fptr;
if ((pass == LAST_PASS) && (xlist))
fprintf(lptr, "#[%i] %s\n", infile_num, input_file[infile_num].name);
return (0);
}